home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / Caml Light 0.7 / Caml Light 0.7 source / src / appli / gui.c < prev    next >
Text File  |  1995-07-04  |  72KB  |  1,086 lines

  1. #include <Controls.h>
  2. #include <Desk.h>
  3. #include <Dialogs.h>
  4. #include <DiskInit.h>
  5. #include <Errors.h>
  6. #include <Events.h>
  7. #include <Files.h>
  8. #include <Fonts.h>
  9. #ifdef __MWERKS__
  10. #include <Gestalt.h>
  11. #else
  12. #include <GestaltEqu.h>
  13. #endif
  14. #include <limits.h>
  15. #include <LowMem.h>
  16. #include <Memory.h>
  17. #include <Menus.h>
  18. #include <OSEvents.h>
  19. #include <OSUtils.h>
  20. #include <Packages.h>
  21. #include <Palettes.h>
  22. #include <Power.h>
  23. #include <QuickDraw.h>
  24. #include <Resources.h>
  25. #include <Scrap.h>
  26. #include <Script.h>
  27. #include <SegLoad.h>
  28. #include <Signal.h>
  29. #include <StandardFile.h>
  30. #include <StdIO.h>
  31. #include <StdLib.h>
  32. #include <TextEdit.h>
  33. #include <ToolUtils.h>
  34. #include <Traps.h>
  35. #include <Types.h>
  36. #include <Windows.h>
  37.  
  38. #if (defined(powerc) && !defined(__MWERKS__)) || __SC__ == 0x705
  39.     QDGlobals    qd;
  40. #endif
  41.  
  42. #include "gui.h"
  43. #include "camlmenus.h"
  44.  
  45. #define rMenuBar        128        /* Liste des menus                */
  46.  
  47. #define mApple            128        /* Menu Pomme                    */
  48. #define iAbout            1        /* item 'A propos...'            */
  49.  
  50. #define mFile            129        /* Menu File                    */
  51. #define iOpen             1        /* item Open...            =O        */
  52. #define iClose             3        /* item Close            =W        */
  53. #define iSave             4        /* item Save            =S        */
  54. #define iInclude        6
  55. #define iCompile        7
  56. #define iLoad           8
  57. #define iLoadObject        9
  58. #define iQuit             11        /* item Quit            =Q        */
  59.  
  60. #define mEdit             130        /* Menu Edit                    */
  61. #define iUndo             1        /* item Undo            =Z        */
  62. #define iCut             3        /* item Cut                =X        */
  63. #define iCopy             4        /* item Copy            =C        */
  64. #define iPaste            5        /* item Paste            =V        */
  65. #define iClear             6        /* item Clear                    */
  66. #define iSelAll            8        /* item Select All        =A        */
  67.  
  68. #define mCaml            131        /* Menu History                    */
  69. #define iShowGraph        1        /* Show Graphic            =G        */
  70. #define iShowHist        2        /* Show History            =H        */
  71. #define iPrevEnt        3        /* Previous Entry        =P        */
  72. #define iNextEnt        4        /* Next Entry            =N        */
  73. #define iInterrupt        6        /* Interrupt Caml        =.        */
  74. #define iGC             7
  75. #define iPref            9        /* item Preferences                */
  76.  
  77. #define rErrorList         128        /* Liste des messages d'erreur                        */
  78. #define eNoMemory         1        /* Not enough memory                                */
  79. #define eNoRessource     2        /* The needed resource cannot be load                */
  80. #define eNoTextEdit     3        /* TextEdit cannot be used                            */
  81. #define eNoScrap         4        /* The clipboard is unusable                        */
  82. #define eNoScrapPut     5        /* Impossible to write on the clipboard                */
  83. #define eNoScrapGet     6        /* Impossible to read the clipborad                    */
  84. #define eNoMoreText     7        /* This window cannot get more memory                */
  85. #define eWrongMachine     8        /* Caml Light cannot run on this type of Macintosh    */
  86. #define eNoMoreHistory    9        /* No more room in the history                        */
  87. #define eTooMuchChars    10        /* Too much characters in this window                */
  88. #define eCannotCreate    11        /* Cannot create the file. */
  89. #define eCannotWrite    12        /* Cannot write to the file. */
  90. #define eCannotReplace    13        /* Cannot replace the file. */
  91.  
  92. #define rErrorAlert        128        /* alerte                        */
  93. #define rAboutAlert        129        /* alerte pour A propos...        */
  94. #define rSizeAlert        130        /* alerte preferences texte        */
  95.  
  96. #define rPreferences    128        /* dialogue Preferences            */
  97. #define iOK                1        /* item OK                        */
  98. #define iCancel            2        /* item Cancel                    */
  99. #define iDefault        3        /* item Default                    */
  100.  
  101. #define iFirstControl    4        /* The first control is Return    */
  102. #define iReturn            4        /* item Return = Send To Caml    */
  103. #define iEnter            5        /* item Enter = Send To Caml    */
  104. #define iShHistory        6        /* item Show History            */
  105. #define iAutoScroll        7        /* item Auto scroll Output        */
  106. #define iSavePos        8        /* item Save position of window    */
  107. #define iPrMaxSize        9        /* item Printer Max Size        */
  108. #define iPrFlushSize    10        /* item Printer Flush Size        */
  109. #define iHiMaxSize        11        /* item History Max Size        */
  110. #define iHiFlushSize    12        /* item History Flush Size        */
  111. #define iTextCreator    13
  112. #define iLastControl    13        /* The last control is TextCreator */
  113.  
  114. #define rPREF            128        /* resource preferences            */
  115.  
  116. #define rWindow            128        /* fenetre de donnees            */
  117.  
  118. #define rWTitle            129        /* Liste des noms de fenetres    */
  119. #define tOutput            1        /* Nom fenetre Output            */
  120. #define tInput            2        /* Nom fenetre Input            */
  121. #define tHistory        3    ail){
  122.     *result = graph_event_queue [graph_event_head];
  123.     result->what = nullEvent;
  124.   }else{
  125.     *result = graph_event_queue [graph_event_tail];
  126.     Incr (graph_event_tail);
  127.   }
  128. }
  129.  
  130. #undef Incr
  131.  
  132. void LookEvent(unsigned long delay)
  133. {
  134.     EventRecord event;
  135.     Boolean eventToProcess;
  136.     RgnHandle mouseRgn;
  137.     WindowPtr window;
  138.     
  139.     do {
  140.         mouseRgn = (inForeground) ? FixCursor() : nil;
  141.         if (inForeground && isTEWindow(window = FrontWindow()))
  142.             TEIdle((TEHandle) ((dataPeek) window)->h);
  143.         if (WNEAvailable)
  144.             eventToProcess = WaitNextEvent(everyEvent, &event, delay, mouseRgn);
  145.         else {
  146.             SystemTask();
  147.             eventToProcess = GetNextEvent(everyEvent, &event);
  148.         }
  149.         graph_event_queue [graph_event_head] = event;
  150.         if (mouseRgn != nil)
  151.             DisposeRgn(mouseRgn);
  152.         if (eventToProcess)
  153.             DoEvent(&event);
  154.     } while (eventToProcess);
  155. }
  156.  
  157. RgnHandle FixCursor(void)
  158. {
  159.     WindowPtr window;
  160.     Point mouse;
  161.     long h;
  162.     Rect r;
  163.     RgnHandle mouseRgn;
  164.     RgnHandle screenRgn;
  165.     
  166.     window = FrontWindow();
  167.     if (isTEWindow(window) || isTextWindow(window)) {
  168.         SetPort(window);
  169.         GetMouse(&mouse);
  170.         h = ((dataPeek) window)->h;
  171.         r = isTEWindow(window) ? (*((TEHandle) h))->viewRect : (*((textHandle) h))->viewRect;
  172.         mouseRgn = NewRgn();
  173.         RectRgn(mouseRgn, &r);
  174.         OffsetRgn(mouseRgn, -window->portBits.bounds.left, -window->portBits.bounds.top);
  175.         if (PtInRect(mouse, &r))
  176.             SetCursor(*GetCursor(iBeamCursor));
  177.         else {
  178.             SetCursor(&qd.arrow);
  179.             r = qd.screenBits.bounds;
  180.             screenRgn = NewRgn();
  181.             RectRgn(screenRgn, &r);
  182.             DiffRgn(screenRgn, mouseRgn, mouseRgn);
  183.             DisposeRgn(screenRgn);
  184.         }
  185.         return mouseRgn;
  186.     }
  187.     SetCursor(&qd.arrow);
  188.     if (isGraphWindow (window) && wait_graph_move){
  189.       wait_graph_move = 0;
  190.       GetMouse (&mouse);
  191.       mouseRgn = NewRgn ();
  192.       SetRectRgn (mouseRgn, mouse.h, mouse.v, mouse.h + 1, mouse.v + 1);
  193.       OffsetRgn (mouseRgn, -window->portBits.bounds.left, -window->portBits.bounds.top);
  194.       return mouseRgn;
  195.     }
  196.     return nil;
  197. }
  198.  
  199. void DoEvent(EventRecord *event)
  200. {
  201.     char key;
  202.     WindowPtr window;
  203.     TEHandle te;
  204.     Point thePoint;
  205.     
  206.     switch (event->what) {
  207.         case mouseDown:
  208.             DoMouseDown(event);
  209.             break;
  210.         case mouseUp:
  211.             push_graph_event ();
  212.             break;
  213.         case keyDown:
  214.         case autoKey:
  215.             key = event->message & charCodeMask;
  216.             window = FrontWindow();
  217.             if (event->modifiers & cmdKey)
  218.                 if (key == CReturn && !(event->modifiers & shiftKey))
  219.                     key = Enter;
  220.                 else {
  221.                     AdjustMenus(window);
  222.                     DoMenuCommand(MenuKey(key), window);
  223.                     return;
  224.                 }
  225.             switch (WindowType(window)) {
  226.                 case tInput:
  227.                     te = (TEHandle) ((dataPeek) window)->h;
  228.                     if (Pref->Return && ((key == CReturn) || (key == Enter)))
  229.                         key = CReturn + Enter - key;
  230.                     if (key != Enter) {
  231.                         if (((*te)->teLength + (*te)->selEnd - (*te)->selStart + 1 < SHRT_MAX)
  232.                             || (key == DelKey)
  233.                             || (key < ' '))
  234.                             TEKey(key, te);
  235.                         else
  236.                             Error(eTooMuchChars);
  237.                     } else {
  238.                         if ((event->modifiers & (shiftKey|cmdKey)) == (shiftKey|cmdKey)) {
  239.                             SendToHistory(te, 1);
  240.                         }else{
  241.                             SendToHistory(te, 0);
  242.                         }
  243.                         if (event->modifiers & optionKey) {
  244.                             AdjustMenus(window);
  245.                             DoMenuCommand(MenuKey('N'), window);
  246.                         } else
  247.                             indexBuffer = **(*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  248.                     }
  249.                     AdjustScrollBars((dataPeek) window);
  250.                     break;
  251.                 case tOutput:
  252.                 case tHistory:
  253.                     SysBeep(1);
  254.                     break;
  255.                 case tGraphic:
  256.                     push_graph_event ();
  257.                     break;
  258.             }
  259.             break;
  260.         case activateEvt:
  261.             DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag));
  262.             break;
  263.         case updateEvt:
  264.             DoUpdate(window = (WindowPtr) event->message);
  265.             break;
  266.         case diskEvt:
  267.             if (HiWord(event->message) != noErr) {
  268.                 SetPt(&thePoint, DIX, DIY);
  269.                 DIBadMount(thePoint, event->message);
  270.             }
  271.             break;
  272.         case app4Evt:
  273.             if (((event->message & osEvtMessageMask) >> 24) == suspendResumeMessage) {
  274.                 inForeground = (event->message & resumeFlag);
  275.                 DoActivate(FrontWindow(), inForeground);
  276.             }
  277.             break;
  278.     }
  279. }
  280.  
  281. void DoMouseDown(EventRecord *event)
  282. {
  283.     WindowPtr window;
  284.     short part;
  285.     Rect r;
  286.     
  287.     part = FindWindow(event->where, &window);
  288.     switch (part) {
  289.         case inMenuBar:
  290.             AdjustMenus(window = FrontWindow());
  291.             DoMenuCommand(MenuSelect(event->where), window);
  292.             break;
  293.         case inSysWindow:
  294.             SystemClick(event, window);
  295.             break;
  296.         case inContent:
  297.             if (window != FrontWindow())
  298.                 SelectWindow(window);
  299.             else
  300.                 DoClickContent(window, event);
  301.             break;
  302.         case inDrag:
  303.             r = qd.screenBits.bounds;
  304.             r.top += GetMBarHeight();
  305.             InsetRect(&r, MARGINDRAG, MARGINDRAG);
  306.             DragWindow(window, event->where, &r);
  307.             break;
  308.         case inGrow:
  309.             DoGrowWindow(window, event);
  310.             break;
  311.         case inGoAway:
  312.             HideWindow(window);
  313.             break;
  314.         case inZoomIn:
  315.         case inZoomOut:
  316.             if (TrackBox(window, event->where, part)) {
  317.                 SetPort(window);
  318.                 EraseRect(&window->portRect);
  319.                 ZoomWindow(window, part, window == FrontWindow());
  320.                 FixViewRect(window);
  321.                 if (isGraphWindow(window)) {
  322.                     switch (part) {
  323.                         case inZoomIn:
  324.                             gp->destRect = gp->destRectZoom;
  325.                             break;
  326.                         case inZoomOut:
  327.                             gp->destRectZoom = gp->destRect;
  328.                             gp->destRect = gp->viewRect;
  329.                             gp->destRect.right = gp->destRect.left + SIZEX;
  330.                             gp->destRect.top = gp->destRect.bottom - SIZEY;
  331.                     }
  332.                     ClipRect(&CAMLGraph->portRect);
  333.                 }
  334.                 InvalRect(&window->portRect);
  335.                 (*((dataPeek) window)->vSBar)->contrlVis = inVisible;        /* pour que AdjustScrollBars ne redessine pas    */
  336.                 (*((dataPeek) window)->hSBar)->contrlVis = inVisible;        /* les controles, ce sera fait via le updateEvt    */
  337.                 AdjustScrollBars((dataPeek) window);
  338.                 FixScrollBar((dataPeek) window);
  339.             }
  340.             break;
  341.     }
  342. }
  343.  
  344. void DoClickContent(WindowPtr window, EventRecord *event)
  345. {
  346.     Point mouse;
  347.     dataPeek doc;
  348.     short max, scale;
  349.     long realMax;
  350.     ControlHandle control;
  351.     TEHandle te;
  352.     TEPtr pte;
  353.     textHandle t;
  354.     textPtr pt;
  355.     graphPeek g;
  356.     
  357.     mouse = event->where;
  358.     doc = (dataPeek) window;
  359.     SetPort(window);
  360.     GlobalToLocal(&mouse);
  361.     switch (WindowType(window)) {
  362.         case tInput:
  363.             te = (TEHandle) doc->h;
  364.             switch (FindControl(mouse, window, &control)) {
  365.                 case 0:
  366.                     if (PtInRect(mouse, &(*te)->viewRect)) {
  367.                         TEClick(mouse, ((event->modifiers & shiftKey) != 0), te);
  368.                         AdjustScrollBars(doc);
  369.                     }
  370.                     break;
  371.                 case inThumb:
  372.                     pte = *te;
  373.                     if (control == doc->vSBar) {
  374.                         max = pte->nLines - (pte->viewRect.bottom - pte->viewRect.top) / pte->lineHeight;    /* il faut avoir le max reel...    */
  375.                         max += (pte->teLength) && (*(*pte->hText + pte->teLength - 1) == '\n');
  376.                     } else
  377.                         max = TEWSIZE - (pte->viewRect.right - pte->viewRect.left + CHARWIDTH - 1) / CHARWIDTH;
  378.                     if (max < GetCtlValue(control)) {
  379.                         if (max < 1)
  380.                             max = 1;
  381.                         (*control)->contrlValue = max;
  382.                         (*control)->contrlMax = max;
  383.                     }
  384.                     if (TrackControl(control, mouse, nil)) {
  385.                         pte = *te;
  386.                         if (control == doc->vSBar)
  387.                             TEScroll(0, pte->viewRect.top - pte->destRect.top - GetCtlValue(control) * pte->lineHeight, te);
  388.                         else
  389.                             TEScroll(pte->viewRect.left - pte->destRect.left - GetCtlValue(control) * CHARWIDTH, 0, te);
  390.                     }
  391.                     AdjustScrollBars(doc);
  392.                     break;
  393.                 default:
  394.                     TrackControl(control, mouse, DoClickTESBarUPP);
  395.                     break;
  396.             }
  397.             break;
  398.         case tOutput:
  399.         case tHistory:
  400.             t = (textHandle) doc->h;
  401.             switch (FindControl(mouse, window, &control)) {
  402.                 case 0:
  403.                     if (PtInRect(mouse, &(*t)->viewRect))
  404.                         SelectText(t, mouse, event->modifiers & shiftKey);
  405.                     break;
  406.                 case inThumb:
  407.                     pt = *t;
  408.                     if (control == doc->vSBar) {
  409.                         realMax = pt->nLines - (pt->viewRect.bottom - pt->viewRect.top) / pt->lineHeight;
  410.                         scale = 1 + realMax / SHRT_MAX;
  411.                         max = realMax / scale;
  412.                     } else
  413.                         max = (pt->destRect.right - pt->destRect.left - pt->viewRect.right + pt->viewRect.left + pt->width - 1) / pt->width;
  414.                     if (max < GetCtlValue(control)) {
  415.                         if (max < 1)
  416.                             max = 1;
  417.                         (*control)->contrlValue = max;
  418.                         (*control)->contrlMax = max;
  419.                     }
  420.                     if (TrackControl(control, mouse, nil)) {
  421.                         pt = *t;
  422.                         if (control == doc->vSBar)
  423.                             VScrollText(t, (pt->viewRect.top - pt->destRect.top) / pt->lineHeight - GetCtlValue(control) * scale);
  424.                         el;
  425.     if (isGraphWindow(window) || (window == CAMLHistory))
  426.         EnableItem(hFile, iClose);
  427.     else
  428.         DisableItem(hFile, iClose);
  429.     if (save){
  430.         EnableItem (hFile, iSave);
  431.     }else{
  432.         DisableItem (hFile, iSave);
  433.     }
  434.     if (reading){
  435.       EnableItem (hFile, iInclude);
  436.       EnableItem (hFile, iCompile);
  437.       EnableItem (hFile, iLoad);
  438.       EnableItem (hFile, iLoadObject);
  439.       EnableItem (hCaml, iGC);
  440.     }else{
  441.       DisableItem (hFile, iInclude);
  442.       DisableItem (hFile, iCompile);
  443.       DisableItem (hFile, iLoad);
  444.       DisableItem (hFile, iLoadObject);
  445.       DisableItem (hCaml, iGC);
  446.     }
  447. }
  448.  
  449. void set_input (char *text, long len)
  450. {
  451.   Rect r;
  452.   TEHandle te = (TEHandle) ((dataPeek) CAMLInput)->h;
  453.  
  454.   SetPort (CAMLInput);
  455.   TEDeactivate(te);
  456.   TESetSelect(0, (*te)->teLength, te);
  457.   TEDelete(te);
  458.   TEActivate(te);
  459.   if (len > 0) {
  460.       TESetText (text, len, te);
  461.       r = CAMLInput->portRect;
  462.       r.right -= SBWIDTH - 1;
  463.       r.bottom -= SBWIDTH - 1;
  464.       EraseRect(&r);
  465.       TEUpdate(&r, te);
  466.   }
  467.   AdjustScrollBars((dataPeek) CAMLInput);
  468. }
  469.  
  470. void DoMenuCommand(long menuResult, WindowPtr window)
  471. {
  472.     short menuID, item, d;
  473.     Str255 DAName;
  474.     Handle h;
  475.     textHandle t;
  476.     TEHandle te;
  477.     bufHandle buffer;
  478.     
  479.     if (menuID = HiWord(menuResult)) {
  480.         item = LoWord(menuResult);
  481.         switch (menuID) {
  482.             case mApple:
  483.                 switch (item) {
  484.                     case iAbout:
  485.                         h = GetResource('ALRT', rAboutAlert);
  486.                         CenterRect((Rect *) *h);
  487.                         Alert(rAboutAlert, nil);
  488.                         break;
  489.                     default:
  490.                         GetItem(GetMHandle(mApple), item, DAName);
  491.                         OpenDeskAcc(DAName);
  492.                 }
  493.                 break;
  494.             case mFile:
  495.                 switch (item) {
  496.                     case iOpen:
  497.                         break;
  498.                     case iClose:
  499.                         if (((WindowPeek) window)->windowKind < 0)
  500.                             CloseDeskAcc(-((WindowPeek) window)->windowKind);
  501.                         else
  502.                             HideWindow(window);
  503.                         break;
  504.                     case iSave:
  505.                         if (((WindowPeek) window)->windowKind < 0){
  506.                           /* Desk Accessory.  Do nothing. */
  507.                         }else{
  508.                           DoSave (window);
  509.                         }
  510.                         break;
  511.                     case iQuit:
  512.                         Quit();
  513.                         break;
  514.                     case iInclude:
  515.                         do_include ();
  516.                         break;
  517.                     case iCompile:
  518.                         do_compile ();
  519.                         break;
  520.                     case iLoad:
  521.                         do_load ();
  522.                         break;
  523.                     case iLoadObject:
  524.                         do_load_object ();
  525.                         break;
  526.                 }
  527.                 break;
  528.             case mEdit:
  529.                 if (!SystemEdit(item - 1))
  530.                     switch (item) {
  531.                         case iUndo:
  532.                             break;
  533.                         case iCut:
  534.                             TECut((TEHandle) ((dataPeek) window)->h);
  535.                             AdjustScrollBars((dataPeek) window);
  536.                             break;
  537.                         case iCopy:
  538.                             if (isTEWindow(window))
  539.                                 TECopy((TEHandle) ((dataPeek) window)->h);
  540.                             else {
  541.                                 t = (textHandle) ((dataPeek) window)->h;
  542.                                 if ((*t)->selStart < (*t)->selEnd)
  543.                                     if (ZeroScrap() != noErr)
  544.                                         Error(eNoScrap);
  545.                                     else {
  546.                                         HLock((*t)->hText);
  547.                                         if (PutScrap((*t)->selEnd - (*t)->selStart, 'TEXT', *(*t)->hText + (*t)->selStart) != noErr)
  548.                                             Error(eNoScrapPut);
  549.                                         HUnlock((*t)->hText);
  550.                                     }
  551.                             }
  552.                             break;
  553.                         case iPaste:
  554.                             te = (TEHandle) ((dataPeek) window)->h;
  555.                             if (TEGetScrapLen() + (*te)->teLength + (*te)->selStart - (*te)->selEnd < SHRT_MAX) {
  556.                                 TEPaste(te);
  557.                                 AdjustScrollBars((dataPeek) window);
  558.                             } else
  559.                                 Error(eTooMuchChars);
  560.                             break;
  561.                         case iClear:
  562.                             TEDelete((TEHandle) ((dataPeek) window)->h);
  563.                             AdjustScrollBars((dataPeek) window);
  564.                             break;
  565.                         case iSelAll:
  566.                             if (isTEWindow(window)) {
  567.                                 te = (TEHandle) ((dataPeek) window)->h;
  568.                                 TESetSelect(0, (*te)->teLength, te);
  569.                             } else {
  570.                                 t = (textHandle) ((dataPeek) window)->h;
  571.                                 InvertText(t, 0, (*t)->selStart);
  572.                                 InvertText(t, (*t)->selEnd, (*t)->teLength);
  573.                                 (*t)->selStart = 0;
  574.                                 (*t)->selEnd = (*t)->teLength;
  575.                             }
  576.                             break;
  577.                     }
  578.                 break;
  579.             case mCaml:
  580.                 switch (item) {
  581.                     case iInterrupt:
  582.                         HiliteMenu(0);
  583.                         raise(SIGINT);
  584.                         break;
  585.                     case iShowHist:
  586.                         ShowWindow(CAMLHistory);
  587.                         SelectWindow(CAMLHistory);
  588.                         break;
  589.                     case iPrevEnt:
  590.                     case iNextEnt:
  591.                         t = (textHandle) ((dataPeek) CAMLHistory)->h;
  592.                         buffer = (*t)->buffer;
  593.                         d = 0;
  594.                         if ((item == iPrevEnt) && (indexBuffer > 2))
  595.                             d = -1;
  596.                         if ((item == iNextEnt) && (indexBuffer < **buffer))
  597.                             d = 1;
  598.                         if (d != 0) {
  599.                             indexBuffer += d;
  600.                             HLock ((*t)->hText);
  601.                             if (indexBuffer < **buffer){
  602.                               set_input (*(*t)->hText + (*buffer) [indexBuffer],
  603.                                          (*buffer) [indexBuffer + 1] - (*buffer)[indexBuffer] - nCR);
  604.                             }else{
  605.                               set_input (nil, 0);
  606.                             }
  607.                         }
  608.                         break;
  609.                     case iShowGraph:
  610.                         ShowWindow(CAMLGraph);
  611.                         SelectWindow(CAMLGraph);
  612.                         break;
  613.                     case iPref:
  614.                         SetPreferences();
  615.                         break;
  616.                     case iGC:
  617.                         do_gc ();
  618.                         break;
  619.                 }
  620.                 break;
  621.         }
  622.         HiliteMenu(0);
  623.     }
  624. }
  625.  
  626. void DoSave (WindowPtr window)
  627. {
  628.   Handle text_handle = (*(textHandle) (((dataPeek) window)->h))->hText;
  629.   DialogTHndl the_dialog;
  630.   Point there;
  631.   Str255 prompt, default_name;
  632.   SFReply reply;
  633.   short file_ref_num;
  634.   short result_code;
  635.   Rect sb = qd.screenBits.bounds;
  636.   long count, creator;
  637.   
  638.   switch (WindowType (window)){
  639.   case tOutput:
  640.     GetIndString (prompt, rMiscStr, sSaveOutput);
  641.     GetIndString (default_name, rMiscStr, sUntitled);
  642.     break;
  643.   case tHistory:
  644.     GetIndString (prompt, rMiscStr, sSaveHistory);
  645.     GetIndString (default_name, rMiscStr, sHistory_ml);
  646.     break;
  647.   default:
  648.     return;
  649.   }
  650.   the_dialog = (DialogTHndl) GetResource ('DLOG', putDlgID);
  651.   if (the_dialog != nil && *the_dialog != nil){
  652.     Rect *r = &(*the_dialog)->boundsRect;
  653.     
  654.     CenterRect (r);
  655.     there.h = r->left;
  656.     there.v = r->top;
  657.   }else{
  658.     there.h = 200;
  659.     there.v = 100;
  660.   }
  661.   SFPutFile (there, prompt, default_name, NULL, &reply);
  662.   if (!reply.good) return;
  663.   result_code = FSDelete (reply.fName, reply.vRefNum);
  664.   if (result_code != noErr && result_code != fnfErr){
  665.     Error (eCannotReplace);
  666.     return;
  667.   }
  668.   memcpy (&creator, Pref->text_creator, 4);
  669.   result_code = Create (reply.fName, reply.vRefNum, creator, 'TEXT');
  670.   if (result_code != noErr){
  671.     Error (eCannotCreate);
  672.     return;
  673.   }
  674.   if (FSOpen (reply.fName, reply.vRefNum, &file_ref_num) != noErr){
  675.     if (result_code == noErr) FSDelete (reply.fName, reply.vRefNum);
  676.     Error (eCannotWrite);
  677.     return;
  678.   }
  679.   count = (*(textHandle) (((dataPeek) window)->h))->teLength;
  680.   if (FSWrite (file_ref_num, &count, *text_handle) != noErr){
  681.     FSClose (file_ref_num);
  682.     if (result_code == noErr) FSDelete (reply.fName, reply.vRefNum);
  683.     Error (eCannotWrite);
  684.     return;
  685.   }
  686.   FSClose (file_ref_num);
  687.   return;
  688. }
  689.  
  690. void SendToHistory(TEHandle te, int no_cr)
  691. {
  692.     bufHandle buffer;
  693.     Size s;
  694.     
  695.     if ((*te)->teLength > 0 || no_cr) {
  696.         buffer = (*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  697.         if (((**buffer + 2) * sizeof(long)) > (s = GetHandleSize((Handle) buffer))) {
  698.             SetHandleSize((Handle) buffer, s + BUFBLOCK);
  699.             if (MemError() != noErr) {
  700.                 Error(eNoMoreHistory);
  701.                 return;
  702.             }
  703.         }
  704.         HLock((*te)->hText);
  705.         DoWrite(CAMLHistory, (char *) *(*te)->hText, (*te)->teLength);
  706.         HUnlock((*te)->hText);
  707.         DoWrite(CAMLHistory, "\n\n", nCR - no_cr);            /* le nombre de '\n' est egal a nCR    - no_cr */
  708.         (*buffer)[++**buffer] = (*((textHandle) ((dataPeek) CAMLHistory)->h))->teLength;
  709.         TEDeactivate(te);
  710.         TESetSelect(0, (*te)->teLength, te);
  711.         TEDelete(te);
  712.         TEActivate(te);
  713.     }
  714. }
  715.  
  716. void GetPreferences(void)
  717. {
  718.   PrefHandle resource;
  719.   
  720.   resource = (PrefHandle) GetResource ('PREF', rPREF);
  721.   if (resource == nil){
  722.     resource = (PrefHandle) NewHandle (sizeof (struct Preferences));
  723.     AddResource ((Handle) resource, 'PREF', rPREF, "\p");
  724.     (*resource)->magic_number = 'WRNG';
  725.   }
  726.   if (resource == nil){
  727.     Error (eNoMemory);
  728.     ExitToShell ();
  729.   }
  730.   if (GetHandleSize ((Handle) resource) != sizeof (struct Preferences))
  731.     SetHandleSize ((Handle) resource, sizeof (struct Preferences));
  732.   HLock ((Handle) resource);
  733.   Pref = *resource;
  734.   if (Pref->magic_number != 'CAML') SetDefaultPrefs ();
  735. }
  736.  
  737. void SetDefaultPrefs (void)
  738. {
  739.   Pref->magic_number = 'CAML';
  740.   Pref->Return = true;
  741.   Pref->ShowHist = false;
  742.   Pref->AutoScroll = true;
  743.   Pref->SavePos = false;
  744.   Pref->PrMaxSize = MAXSIZE * 1024;
  745.   Pref->PrFlushSize = FLUSHSIZE * 1024;
  746.   Pref->HiMaxSize = MAXSIZE / 2 * 1024;
  747.   Pref->HiFlushSize = FLUSHSIZE / 2 * 1024;
  748.   memcpy (Pref->text_creator, "ttxt", 4);
  749. }
  750.  
  751. void GetWindowPos(WindowPtr window, Rect *r)
  752. {
  753.   Point *p = (Point *) r;
  754.   
  755.   SetPort (window);
  756.   *r = window->portRect;
  757.   LocalToGlobal (&p[0]);
  758.   LocalToGlobal (&p[1]);
  759. }
  760.  
  761. void fit_in_screen (Rect *w, Rect *screen)
  762. {
  763.   Rect temp;
  764.  
  765.   if (w->bottom - w->top > screen->bottom - screen->top){
  766.     w->bottom = w->top + screen->bottom - screen->top;
  767.   }
  768.   if (!SectRect (w, screen, &temp)){
  769.     w->bottom = screen->top + w->bottom - w->top;
  770.     w->top = screen->top;
  771.     w->right = screen->left + w->right - w->left;
  772.     w->left = screen->left;
  773.   }
  774.   if (w->top < screen->top){
  775.     w->bottom += screen->top - w->top;
  776.     w->top = screen->top;
  777.   }
  778. }
  779.  
  780. void send_to_caml (char *text)
  781. {
  782.   set_input (text, strlen (text));
  783.   SendToHistory ((TEHandle) ((dataPeek) CAMLInput)->h, 0);
  784.   indexBuffer = **(*((textHandle) ((dataPeek) CAMLHistory)->h))->buffer;
  785. }
  786.  
  787. void SetWindowPos(void)
  788. {
  789.   Rect screen;
  790.  
  791.   screen = qd.screenBits.bounds;
  792.   screen.top += GetMBarHeight() + SBWIDTH;
  793.   InsetRect(&screen, MARGINDRAG, MARGINDRAG);
  794.   if (Pref->SavePos){
  795.     /* Only change windows that are completely off-screen
  796.        or too big. */
  797.     fit_in_screen (&Pref->PrWindowRect, &screen);
  798.     fit_in_screen (&Pref->LiWindowRect, &screen);
  799.     fit_in_screen (&Pref->HiWindowRect, &screen);
  800.     fit_in_screen (&Pref->GrWindowRect, &screen);
  801.   }else{
  802.     SetRect (&Pref->LiWindowRect,
  803.              screen.left, screen.bottom - WMINSIZE,
  804.              screen.left + WNORMWIDTH, screen.bottom);
  805.     fit_in_screen (&Pref->LiWindowRect, &screen);
  806.     SetRect (&Pref->PrWindowRect,
  807.              screen.left, screen.top,
  808.              screen.left + WNORMWIDTH, Pref->LiWindowRect.top - WNDMARG);
  809.     fit_in_screen (&Pref->PrWindowRect, &screen);
  810.     SetRect (&Pref->HiWindowRect,
  811.              Pref->PrWindowRect.right + MARGINDRAG, screen.top,
  812.              Pref->PrWindowRect.right + MARGINDRAG + WNORMWIDTH, screen.bottom);
  813.     if (Pref->HiWindowRect.right > screen.right) Pref->HiWindowRect.right = screen.right;
  814.     if (Pref->HiWindowRect.right - Pref->HiWindowRect.left < WMINSIZE){
  815.       Pref->HiWindowRect.left = Pref->HiWindowRect.right - WMINSIZE;
  816.     }
  817.     fit_in_screen (&Pref->HiWindowRect, &screen);
  818.     SetRect (&Pref->GrWindowRect,
  819.              screen.left, screen.top,
  820.              screen.left + SIZEX + SBWIDTH -1, screen.top + SIZEY + SBWIDTH -1);
  821.     fit_in_screen (&Pref->GrWindowRect, &screen);
  822.   }
  823. }
  824.  
  825. void SetPrefValues(ControlHandle *control)
  826. {
  827.     short item;
  828.     Str255 text;
  829.     long size[4];
  830.     
  831.     SetCtlValue(ctl(iReturn), Pref->Return);
  832.     SetCtlValue(ctl(iEnter), 1 - Pref->Return);
  833.     SetCtlValue(ctl(iShHistory), Pref->ShowHist);
  834.     SetCtlValue(ctl(iAutoScroll), Pref->AutoScroll);
  835.     SetCtlValue(ctl(iSavePos), Pref->SavePos);
  836.     size[0] = Pref->PrMaxSize;
  837.     size[1] = Pref->PrFlushSize;
  838.     size[2] = Pref->HiMaxSize;
  839.     size[3] = Pref->HiFlushSize;
  840.     for (item = iPrMaxSize; item <= iHiFlushSize; item++) {
  841.         NumToString(size[item - iPrMaxSize] / 1024, text);
  842.         SetIText((Handle) ctl(item), text);
  843.     }
  844.     text [0] = 4;
  845.     memcpy (&text [1], Pref->text_creator, 4);
  846.     SetIText ((Handle) ctl (iTextCreator), text);
  847. }
  848.  
  849. void SetPreferences(void)
  850. {
  851.     DialogPtr dialog;
  852.     short item, i;
  853.     long size[4];
  854.     Handle resHandle, itemHandle;
  855.     ControlHandle control[iLastControl - iFirstControl + 1];
  856.     Rect r;
  857.     Str255 text;
  858.     
  859.     if ((resHandle = GetResource('DLOG', rPreferences)) == nil)
  860.         Error(eNoRessource);
  861.     else {
  862.         CenterRect((Rect *) *resHandle);
  863.         dialog = GetNewDialog(rPreferences, nil, (WindowPtr) (-1));
  864.         for (item = iFirstControl; item <= iLastControl; item ++)
  865.             GetDItem(dialog, item, &i, (Handle *) &ctl(item), &r);
  866.         SetPrefValues(control);
  867.         GetDItem(dialog, iOK, &i, &itemHandle, &r);
  868.         DoActivate(FrontWindow(), false);
  869.         SetPort(dialog);
  870.         PenSize(3,3);
  871.         InsetRect(&r, -4, -4);
  872.         ShowWindow(dialog);
  873.         FrameRoundRect(&r, 16, 16);
  874.         do {
  875.             ModalDialog(nil, &item);
  876.             switch (item) {
  877.                 case iOK:
  878.                     for(i = iPrMaxSize; i <= iHiFlushSize; i++) {
  879.                         GetIText((Handle) ctl(i), text);
  880.                         StringToNum(text, &size[i - iPrMaxSize]);
  881.                         if ((size[i - iPrMaxSize] *= 1024) <= 0)
  882.                             break;
  883.                     }
  884.     
  885.             AdjustScrollBars(doc);
  886.             return;
  887.         } else
  888.             Error(eNoTextEdit);
  889.     } else
  890.         Error(eNoMemory);
  891.     Pref->SavePos = false;
  892.     Quit();
  893. }
  894.  
  895. Boolean OpenGraph(void)
  896. {
  897.     dataPeek doc;
  898.     Rect r;
  899.     
  900.     if (DoNew(tGraphic, &Pref->GrWindowRect)) {
  901.         graph_event_head = graph_event_tail = 0;
  902.         CAMLGraph = (WindowPtr) (doc = WList);
  903.         doc->h = (long) NewPtr(sizeof(graphRecord));
  904.         if (doc->h != nil) {
  905.             FixViewRect(CAMLGraph);
  906.             CAMLOffScreen = (GrafPtr) doc->h;
  907.             r = gp->viewRect;
  908.             r.right = r.left + SIZEX;
  909.             r.bottom = r.top + SIZEY;
  910.             if (color_qd){
  911.               GDHandle the_max_device, old_device;
  912.               CTabHandle color_map;
  913.               Rect wide_open = {-32000, -32000, 32000, 32000};
  914.               CGrafPtr color_off_screen = (CGrafPtr) CAMLOffScreen;
  915.               long off_row_bytes;
  916.               
  917.               the_max_device = GetMaxDevice (&wide_open);
  918.               old_device = GetGDevice ();
  919.               CAMLGDevice = NewGDevice (0, 0);
  920.               max_depth = (*(*the_max_device)->gdPMap)->pixelSize;
  921.               **(*CAMLGDevice)->gdPMap = **(*the_max_device)->gdPMap;
  922.               off_row_bytes = (max_depth * (r.right - r.left) + 31) / 32 * 4;
  923.               (*(*CAMLGDevice)->gdPMap)->rowBytes = off_row_bytes + 0x8000;
  924.               (*(*CAMLGDevice)->gdPMap)->baseAddr = NewPtr (off_row_bytes * (long) (r.bottom - r.top));
  925.               if ((*(*CAMLGDevice)->gdPMap)->baseAddr == nil){
  926.                 DoClose (CAMLGraph);
  927.                 return false;
  928.               }
  929.               (*(*CAMLGDevice)->gdPMap)->bounds = r;
  930.               color_map = (*(*the_max_device)->gdPMap)->pmTable;
  931.               if (HandToHand ((Handle *) &color_map) != noErr){
  932.                 DoClose (CAMLGraph);
  933.                 return false;
  934.               }
  935.               (*(*CAMLGDevice)->gdPMap)->pmTable = color_map;
  936.               SetGDevice (CAMLGDevice);
  937.               MakeITable (nil, nil, (*the_max_device)->gdResPref);
  938.               if (QDError () != noErr){
  939.                 SetGDevice (old_device);
  940.                 DoClose (CAMLGraph);
  941.                 return false;
  942.               }
  943.               OpenCPort (color_off_screen);
  944.               SetGDevice (old_device);
  945.               SetPalette (CAMLGraph, nil, 1);
  946.             }else{
  947.               max_depth = 1;
  948.               OpenPort(CAMLOffScreen);
  949.               CAMLOffScreen->portBits.rowBytes = (r.right - r.left + 31) / 32 * 4;
  950.               CAMLOffScreen->portBits.baseAddr = NewPtr(CAMLOffScreen->portBits.rowBytes * (long) (r.bottom - r.top));
  951.               CAMLOffScreen->portBits.bounds = r;
  952.               if (CAMLOffScreen->portBits.baseAddr == nil){
  953.                 DoClose (CAMLGraph);
  954.                 return false;
  955.               }
  956.             }
  957.             CAMLOffScreen->portRect = r;
  958.             EraseRect(&r);
  959.             r.bottom = gp->viewRect.bottom;
  960.             r.top = r.bottom - SIZEY;
  961.             gp->destRect = r;
  962.             gp->destRectZoom = r;
  963.             r = qd.screenBits.bounds;
  964.             r.top += GetMBarHeight() + SBWIDTH;
  965.             InsetRect(&r, MARGINDRAG, MARGINDRAG);
  966.             if (r.right - r.left > SIZEX + SBWIDTH - 1)
  967.                 r.left = r.right - SIZEX - SBWIDTH + 1;
  968.             if (r.bottom - r.top > SIZEY + SBWIDTH - 1)
  969.                 r.top = r.bottom - SIZEY - SBWIDTH + 1;
  970.             (*((WStateDataHandle) ((WindowPeek) CAMLGraph)->dataHandle))->stdState = r;
  971.             TextFont(monaco);
  972.             TextSize(FONTSIZE);
  973.             SetPort(CAMLGraph);
  974.             AdjustScrollBars(doc);
  975.             EnableItem(GetMHandle(mCaml), iShowGraph);
  976.             SelectWindow(CAMLGraph);
  977.             return true;
  978.         }
  979.         DoClose(CAMLGraph);
  980.     }
  981.     return false;
  982. }
  983.  
  984. void DoClose(WindowPtr window)
  985. {
  986.     dataPeek doc;
  987.     
  988.     doc = (dataPeek) window;
  989.     if (doc->h != nil)
  990.         switch (WindowType(window)) {
  991.             case tInput:
  992.                 TEDispose((TEHandle) doc->h);
  993.                 break;
  994.             case tOutput:
  995.             case tHistory:
  996.                 if ((*((textHandle) doc->h))->hText != nil)
  997.                     DisposeHandle((*((textHandle) doc->h))->hText);
  998.                 if ((window == CAMLHistory) && ((*((textHandle) doc->h))->buffer != nil))
  999.                     DisposeHandle((Handle) (*((textHandle) doc->h))->buffer);
  1000.                 DisposeHandle((Handle) doc->h);
  1001.                 break;
  1002.             case tGraphic:
  1003.                 GetWindowPos(CAMLGraph, &Pref->GrWindowRect);
  1004.                 if (color_qd){
  1005.                   if ((*((CGrafPtr) CAMLOffScreen)->portPixMap)->baseAddr != nil)
  1006.                     DisposePtr ((*((CGrafPtr) CAMLOffScreen)->portPixMap)->baseAddr);
  1007.                   CloseCPort ((CGrafPtr) CAMLOffScreen);
  1008.                   DisposGDevice (CAMLGDevice);
  1009.                   CAMLGDevice = nil;
  1010.                 }else{
  1011.                   if (CAMLOffScreen->portBits.baseAddr != nil)
  1012.                     DisposePtr(CAMLOffScreen->portBits.baseAddr);
  1013.                   ClosePort(CAMLOffScreen);
  1014.                 }
  1015.                 DisposePtr((Ptr) CAMLOffScreen);
  1016.                 DisableItem(GetMHandle(mCaml), iShowGraph);
  1017.                 CAMLGraph = nil;
  1018.                 CAMLOffScreen = nil;
  1019.         }
  1020.     CloseWindow(window);
  1021.     if (doc->prevWindow == nil)
  1022.         WList = doc->nextWindow;
  1023.     else
  1024.         (doc->prevWindow)->nextWindow = doc->nextWindow;
  1025.     if (doc->nextWindow != nil)
  1026.         (doc->nextWindow)->prevWindow = doc->prevWindow;
  1027.     DisposePtr((Ptr) window);
  1028. }
  1029.  
  1030. void FixViewRect(WindowPtr window)
  1031. {
  1032.     Rect viewRect;
  1033.     long h;
  1034.     short height;
  1035.     
  1036.     if (isGraphWindow(window)) {
  1037.         viewRect = window->portRect;
  1038.         viewRect.right -= SBWIDTH - 1;
  1039.         viewRect.bottom -= SBWIDTH - 1;
  1040.         ((graphPeek) ((dataPeek) window)->h)->viewRect = viewRect;
  1041.     } else {
  1042.         viewRect.top = TXTMARG;
  1043.         viewRect.left = TXTMARG;
  1044.         viewRect.bottom = window->portRect.bottom - SBWIDTH + 1 - TXTMARG;
  1045.         viewRect.right = window->portRect.right - SBWIDTH + 1;
  1046.         if (isTEWindow(window))
  1047.             viewRect.right -= 2;
  1048.         h = ((dataPeek) window)->h;
  1049.         height = (isTEWindow(window)) ? (*((TEHandle) h))->lineHeight : (*((textHandle) h))->lineHeight;
  1050.         viewRect.bottom = viewRect.top + ((viewRect.bottom - viewRect.top) / height) * height;
  1051.         if (isTEWindow(window))
  1052.             (*((TEHandle) h))->viewRect = viewRect;
  1053.         else
  1054.             (*((textHandle) h))->viewRect = viewRect;
  1055.     }
  1056. }
  1057.  
  1058. void FixScrollBar(dataPeek doc)
  1059. {
  1060.     Rect r;
  1061.     
  1062.     r = ((WindowPtr) doc)->portRect;
  1063.     (*doc->vSBar)->contrlVis = inVisible;
  1064.     (*doc->hSBar)->contrlVis = inVisible;
  1065.     SizeControl(doc->vSBar, SBWIDTH, r.bottom - r.top - SBWIDTH + 3);
  1066.     MoveControl(doc->vSBar, r.right - SBWIDTH + 1, -1);
  1067.     SizeControl(doc->hSBar, r.right - r.left - SBWIDTH + 3, SBWIDTH);
  1068.     MoveControl(doc->hSBar, -1, r.bottom - SBWIDTH + 1);
  1069.     (*doc->vSBar)->contrlVis = Visible;
  1070.     (*doc->hSBar)->contrlVis = Visible;
  1071. }
  1072.  
  1073. void Error(short error)
  1074. {
  1075.     Str255 message;
  1076.     Handle h;
  1077.     
  1078.     SetCursor(&qd.arrow);
  1079.     GetIndString(message, rErrorList, error);
  1080.     ParamText(message, "\p", "\p", "\p");
  1081.     h = GetResource('ALRT', rErrorAlert);
  1082.     CenterRect((Rect *) *h);
  1083.     StopAlert(rErrorAlert, nil);
  1084.     ReleaseResource(h);
  1085. }
  1086.